#include "xformat.h"
#include <stdio.h>
#include <windows.h>


namespace xge{
namespace xge_internal {

  bool Format::FormatString( const char_t* format , va_list var ) {
    if( buffer_ == NULL ) {
      size_ = MAX_CHAR_HEAP_BUFFER_SIZE ;
      buffer_ = (char_t*)XMalloc(MAX_CHAR_HEAP_BUFFER_SIZE);
    }
    // getting the buffer
    static const size_t kMaxLoopTimes = 5; // 5 times to expanded
    static const size_t kIncRatio = 2 ; // 4 times to expanded , so the final buffer is 2^5 = 32 * oroginal buffer 

    size_t loop_times = 0;

    do {
      ++loop_times ;

      int ret = 
#ifdef XGE_USE_WIDE_CHAR
        vswprintf(buffer_,size_,format,var);
#else
        vsprintf_s(buffer_,size_,format,var);
#endif
      if( ret >= (int)size_ ) {
        size_ *= kIncRatio ;
        buffer_ = (char_t*)XRealloc( buffer_ , size_ );
        continue;
      } else if( ret < 0 ) {
        // error
        XFree(buffer_);
        buffer_ = NULL;
        size_ = 0;
        return false;
      } else {
        return true;
      }

    } while( loop_times <  kMaxLoopTimes ) ;// reaching the bounded

    XFree( buffer_ );
    buffer_ = NULL ;
    size_ = 0;

    return false;
  }


  int GetAnsiStr2UnicodeBufferSize( const char* in_str ) {
    wchar_t bufer[1];
    return ::MultiByteToWideChar( CP_UTF8 , 0 , in_str , -1 , bufer , 0 );
  }

  int ConvertAnsiStr2Unicode( const char* in_str , wchar_t* out_strbuf , size_t max_size ) {
    return ::MultiByteToWideChar( CP_UTF8 , 0 , in_str , -1 , out_strbuf , max_size ) ;
  }


} // namespace xge_internal
}//namespace xge